package model;

/*
 * Created on Dec 6, 2007 
 */

import java.io.File;
import java.util.ArrayList;

import javax.vecmath.Point3f;

/**
 * Un objet jtsMesh est represente par 2 tableaux contenants des coordonnees 
 * d'un maillage et indices de ses facettes triangulaires. 
 * 
 * jtsDo utilise jts_reaction pour pour obtenir, sous la forme d'une matrice de 
 * 13 de largeur, differentes courbures avec leurs directions associees a partir
 *  d'un objet jtsMesh.
 * 
 * jtsDoubleCurvatures utilise jts_double_curvatures pour obtnir en meme temps 
 * les courbures moyennes et gaussiennes a partir d'un objet jtsMesh.
 * 
 * jtsMeanCurvatures utilise jts_mean_curvatures pour obtnir uniquement les 
 * courbures moyennes a partir d'un objet jtsMesh.
 * 
 * jtsGaussianCurvatures utilise jts_gaussian_curvatures pour obtnir uniquement 
 * les courbures gaussiennes a partir d'un objet jtsMesh.
 *
 * @author M.C.Boulahiya
 */
public class JtsMesh {
	float[][] vertices;
	int[][] triangles;
	
	native static double[][] jts_reaction(float[] vertices[], int[] triangles[]);
	native static double[][] 
	                jts_double_curvatures(float[] vertices[], int[] triangles[]);
	native static double[] 
	                  jts_mean_curvatures(float[] vertices[], int[] triangles[]);
	native static double[] 
	              jts_gaussian_curvatures(float[] vertices[], int[] triangles[]);

	//Load the library
	static {
		//appendToJavaLibraryPath("/home/potier/Equipe/Maiza/Programmation/JNI/lib");
		//System.loadLibrary("jtsrbf");
		System.loadLibrary("jts");
	}
	
	/**
	 * Default Constructor.
	 * @param coords
	 * @param coorInds
	 */
	public JtsMesh(Point3f[] coords, int[] coorInds) {
		this.vertices = new float[coords.length][3];
		int in = 0;
		for (Point3f point3f : coords) {
			float[] point = new float[3];
			point[0] = point3f.x;
			point[1] = point3f.y;
			point[2] = point3f.z;
			this.vertices[in++] = point;
		}
		this.triangles = new int[coorInds.length/3][3];
		for (in = 0; in < coorInds.length; in += 3) {
			int[] triangle = new int[3];
			triangle[0] = coorInds[in];
			triangle[1] = coorInds[in+1];
			triangle[2] = coorInds[in+2];
			this.triangles[in/3] = triangle;
		}
	}
	
	/**
	 * @param coords
	 * @param coordIdxList
	 */
	public JtsMesh(Point3f[] coords, ArrayList<Integer> coordIdxList) {
		this.vertices = new float[coords.length][3];
		int in = 0;
		for (Point3f point3f : coords) {
			float[] point = new float[3];
			point[0] = point3f.x;
			point[1] = point3f.y;
			point[2] = point3f.z;
			this.vertices[in++] = point;
		}
		this.triangles = new int[coordIdxList.size()/3][3];
		for (in = 0; in < coordIdxList.size(); in += 3) {
			int[] triangle = new int[3];
			triangle[0] = coordIdxList.get(in);
			triangle[1] = coordIdxList.get(in+1);
			triangle[2] = coordIdxList.get(in+2);
			this.triangles[in/3] = triangle;
		}
	}
	
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		Point3f[] coords = {			
        new Point3f( 0.f,0.f,0.f ),
   			new Point3f( 0.f,0.f,1.f ),
    		new Point3f( 0.f,1.f,0.f ),
        new Point3f( 0.f,1.f,1.f ),
        new Point3f( 1.f,0.f,0.f ),
        new Point3f( 1.f,0.f,1.f ),
    		new Point3f( 1.f,1.f,0.f ),
        new Point3f( 1.f,1.f,1.f )
		};
		int[] coorInds = {			
      	0,1,2,
    		1,2,3,
        4,5,6,
    		5,6,7,
        0,1,4,
      	1,4,5,
      	2,3,6,
    		3,6,7,
        0,2,4,
    		2,4,6,
        1,3,5,
      	3,5,7
		};
		
		JtsMesh jmesh = new JtsMesh(coords, coorInds);

		double[][] res13 = jmesh.jtsDo();
		for (int i = 0; i < coords.length; i++) {
      for (int j = 0; j < 13; j++) { //Gaussian/Mean Normal(3)/Mean/Principal(2)/directions(6)
      	System.out.print(" " + res13[i][j]);
      }
      System.out.println();
		}
		
		double[][] res2 = jmesh.jtsDoubleCurvatures();
		for (int i = 0; i < coords.length; i++) {
      //Gaussian/Mean
			System.out.println(" " + res2[i][0]+" " + res2[i][1]);
		}
		
		double[] res1Mean = jmesh.jtsMeanCurvatures();
		for (int i = 0; i < coords.length; i++) {
      //Mean
			System.out.println(" " + res1Mean[i]);
		}
		
		double[] res1Gaussian = jmesh.jtsGaussianCurvatures();
		for (int i = 0; i < coords.length; i++) {
      //Gaussian
			System.out.println(" " + res1Gaussian[i]);
		}
		
	}

	public static void appendToJavaLibraryPath(String newPath) {
		String javaLibraryPath = System.getProperty("java.library.path");
		System.out.println(javaLibraryPath);
		System.setProperty("java.library.path", 
				javaLibraryPath + File.pathSeparatorChar + newPath);
		javaLibraryPath = System.getProperty("java.library.path");
		System.out.println(javaLibraryPath);
	}
	
	public double[][] jtsDo() {
		return jts_reaction(this.vertices, this.triangles);
	}
	
	public double[][] jtsDoubleCurvatures() {
		return jts_double_curvatures(this.vertices, this.triangles);
	}
	
	public double[] jtsMeanCurvatures() {
		return jts_mean_curvatures(this.vertices, this.triangles);
	}

	public double[] jtsGaussianCurvatures() {
		return jts_gaussian_curvatures(this.vertices, this.triangles);
	}
	
}// End of class JtsMesh

/*
gcc -fPIC -g -Wall `gts-config --cflags gts` -c -o jts_curvature.o jts_curvature.c
javac JtsMesh.java
javah -jni model.JtsMesh // a realiser sur le .class
gcc -o libjts.so -shared -Wl,-soname,libnative.so \
-I/usr/lib/jvm/java-1.5.0-sun-1.5.0.08/include/ \
-I/usr/lib/jvm/java-1.5.0-sun-1.5.0.08/include/linux/ \
-static -lc -g `gts-config --libs gts` -lm jts_curvature.o model_JtsMesh.c
env
setenv LD_LIBRARY_PATH /home/potier/Equipe/Maiza/Programmation/JNI/:.
su 
sudo cp lib/libjts.so /usr/lib/jvm/java-1.5.0-sun-1.5.0.08/jre/lib/i386 
java -verbose:jni TestJNI
*/

//La librarie Jts utilisee normalement est jts
//La librarie Jts utilisee dans SemanticArchaeo est jts_m
//La librarie Jts utilisee sans la fonction revert_bad_faces est jtsrbf

// End of file JtsMesh.java